/*
    isLeapYear 判断闰年
        @param  number  year    输入的需要判断的年份 必须是数值类型
        @return boolean         如果是闰年返回值是true 如果不是闰年返回值是false

        先对输入的数据进行判断 如果不能转化为数值类型 返回值 是 报错信息
*/

function isLeapYear(year) {
    // 将输入的数据转化为数值类型
    year = Number(year);

    // 如果 输入的数据 转化结果是 NaN 执行报错
    if (isNaN(year)) return '您输入的数据不符合格式';

    // 判断 是不是闰年 返回结果
    return (year % 400 === 0) || ((year % 4 === 0) && (year % 100 !== 0)) ? true : false;

}


/*
    isPalindromicString    判断回文字符串
        @param  string  str 输入的需要判断的字符串  如果不是字符串类型会转化为字符串类型
        @return boolean     如果是回文字符串 返回值是 true 如果不是回文字符串返回值是 false

*/

function isPalindromicString(str) {
    // 将输入的数据转化为字符串类型
    str = String(str);

    // 将 字符串 每一个字符 分割成数组
    var arr = str.split('');

    // 反转数组
    arr.reverse();

    // 将反转数组数据拼接成字符串 没有间隔符号
    var newStr = arr.join('');

    // 判断 新字符串 和 原始字符串 是不是 全等
    return str === newStr ? true : false;
}


/*
    getGCD_LCM  获取 最大公约数 最小公倍数

        @param  number  num1    输入的第一个数值
        @param  number  num2    输入的第二个数值

        @return object  obj     返回获取的最大公约数 最小公倍数 
                                gcd键名存储的是 最大公约数
                                lcm键名存储的是 最小公倍数

        输入的 num1  num2 必须是 数值类型
        如果输入的不是数值类型 返回值 是 报错信息

        num1 num2 会进行排序处理 输入的顺序没有要求
*/

function getGCD_LCM(num1, num2) {
    // 先转化为数值类型
    num1 = Number(num1);
    num2 = Number(num2);

    // 判断 有没有 NaN
    if (isNaN(num1) || isNaN(num2)) return '您输入的数据不符合格式';

    // 对 num1 num2 数值 进行排序
    var min = Math.min(num1, num2);
    var max = Math.max(num1, num2);

    // 创建对象 存储 获取的结果
    var obj = {
        gcd: 0,
        lcm: 0,
    };

    // 判断 最大公约数 最小公倍数
    if (max % min === 0) {
        // 如果可以整除 
        // max 是 最小公倍 min 是 最大公约
        // 给对象赋值
        obj.gcd = min;
        obj.lcm = max;

    } else {
        // 不能整除 通过 循环 判断 最大公约数 最小公倍数 

        // 最大公约数 从 min-1 开始 循环至 1 第一个 可以整除 min max 的是 最大公约数
        for (var i = min - 1; i >= 1; i--) {
            if (max % i === 0 && min % i === 0) {
                // 给对象  gcd 属性 赋值 i 数值
                obj.gcd = i;
                // 终止循环
                break;
            }
        }

        // 最小公倍数 从 max+1 开始 循环至 max*min 第一个 可以同时 被 min max 整除的是 最小公倍数
        for (var i = max + 1; i <= min * max; i++) {
            if (i % min === 0 && i % max === 0) {
                // 给 对象 lcm 属性 赋值 i 数值
                obj.lcm = i;
                // 终止循环
                break;
            }
        }

    }

    // 判断结束 对象中存储 最大公约 最小公倍 
    // 返回这个对象
    return obj;

}

//  myGetTime    获取时间对象数据
//      @param  string  time    输入的时间字符串
//      如果没有输入实参 按照 当前时间获取时间数据
function myGetTime(time) {
    // 如果 time 没有 输入 实参 也就是 存储的是 undefined 
    // 获取 当前时间对象
    // 如果 time 已经 输入 实参 也就是 存储的是 时间字符串
    // 获取 实参数据 对应的 时间对象
    var timeObj = time === undefined ? new Date() : new Date(time);

    // 获取数据 设定给对象 作为 返回值

    // 获取年 
    var year = timeObj.getFullYear();

    // 获取月数字
    var monthNum = timeObj.getMonth() + 1;

    // 获取月文字
    var mothArr = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
    var monthStr = mothArr[timeObj.getMonth()];

    // 获取日期
    var day = timeObj.getDate();

    // 获取星期
    var weekArr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
    var week = weekArr[timeObj.getDay()];

    // 获取小时
    var hours = timeObj.getHours();

    // 获取分钟
    var minutes = timeObj.getMinutes();

    // 获取小时
    var seconds = timeObj.getSeconds();

    // 作为返回值 一般不会 前置补零
    return {
        // 键名是 我们自己定义的 year 
        // 键值是 上面变量year存储的数值
        // year : year ,
        // 要是 定义 一个 year 就可以了 
        // year : year , ---- 写一个 year 就可以了

        year, monthNum, monthStr, day, week, hours, minutes, seconds
    };

}


//  myGetTimeDifference  获取时间差数据
//      @param  string  endTime     结束时间字符串   
//      @param  string  startTime   起始时间字符串
//      @return object              返回时间差结果的 天 小时 分钟 秒
//      如果没有输入起始时间 以 当前时间 作为 起始时间
function myGetTimeDifference(endTime, startTime) {
    // 必须要有终止时间
    // 如果没有输入 最终时间 返回值 是 报错信息
    if (endTime === undefined) return '您必须输入一个终止时间';

    // 创建终止时间对象 
    var endTimeObj = new Date(endTime);

    // 创建起始时间对象
    // 如果 startTime 没有实参 当前时间作为起始时间
    var startTimeObj = startTime === undefined ? new Date() : new Date(startTime);

    // 计算时间差 转化为 秒数
    var time = parseInt((endTimeObj.getTime() - startTimeObj.getTime()) / 1000);

    // 总秒数 转化为 对应的天
    var days = parseInt(time / (24 * 60 * 60));

    // 计算小时
    var hours = parseInt((time % (24 * 60 * 60)) / (60 * 60));

    // 计算分钟
    var minutes = parseInt((time % (60 * 60)) / 60);

    // 计算秒
    var seconds = time % 60;

    // 以对象的形式 返回结果
    return { days, hours, minutes, seconds };

}

// 4位年份转化为 四位汉字
function setYearStr(year) {
    // 定义一个数组 内容是 数字对应的汉字
    var arr = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];

    // 输入的 year 是 4位 年份

    // 获取 每一位上 年份的数字
    var a = parseInt(year / 1000);
    var b = parseInt(year % 1000 / 100);
    var c = parseInt(year % 100 / 10);
    var d = year % 10;

    return `${arr[a]}${arr[b]}${arr[c]}${arr[d]}`;
}


// 其他时间数字 转化为 对应的 时间汉字
function setOtherStr(time) {
    var arr = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];

    // 如果 数值 是 0  返回的 汉字 就是 零
    if (time === 0) {
        return arr[time];

        // 如果 数值 是 10 返回的 汉字 就是 十
    } else if (time === 10) {
        return '十';

        // 如果 数值 可以被 10 整除 
        // 获取 十位的数字 返回值 是 十位数字 对应汉字 拼接 十
    } else if (time % 10 === 0) {
        var a = time / 10;
        return arr[a] + '十';

        // 如果 数值 1 - 9 返回值 是 数字对应的汉字
    } else if (time >= 1 && time <= 9) {
        return arr[time];

        // 如果 数值是 11 - 19 
        // 获取 个位数字 返回值是 十 拼接 个位数字对应的汉字
    } else if (time >= 11 && time <= 19) {
        var a = time % 10;
        return '十' + arr[a];

        // 其他情况 21-29  31-39  41-49  51-59
        // 获取 十位 个位的数字 
        // 返回值 是 十位数字对应的汉字 拼接 十 拼接个位数字对应的汉字
    } else {
        var a = parseInt(time / 10);
        var b = time % 10;
        return arr[a] + '十' + arr[b];

    }

}


/*  
    myGetVc     获取随机验证码

        @param  object  object  输入的验证码函数的实参 
                                键名必须是 str length repeat
                                str 验证码内容字符串
                                length  验证码长度
                                repeat  验证码能不能重复
        
        @return string  vc      生成的随机验证码内容

        repeat  最终默认值对象中存储的 必须是 布尔类型 true / false

        length  最终默认值对象中存储的 必须是 可以转化为数值类型的

        str     最终默认值对象中存储的 必须是 字符串类型

        如果 repeat 是 true  验证码内容可以重复
        如果 repeat 是 false 验证码内容不能重复

        

*/
function myGetVc(object) {


    // 设定对象 存储 默认值
    var oldValObj = {
        str: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        length: 6,
        repeat: true,
    }

    // 判断 如果 形参object中 不是 undefined
    // 也就是 存储了实参
    // 再触发执行之后的程序 实参数据覆盖默认值操作
    if (object !== undefined) {


        // // 循环遍历 object 
        // for( var key in object ){
        //     // 当 object 中的键名 也是 默认值对象oldValObj 中的键名
        //     // 使用 object中这个键名的键值 覆盖 默认值对象oldValObj中相同键名的键值
        //     if( oldValObj[key] !== undefined ){
        //         oldValObj[key] = object[key];
        //     }
        // }


        // 循环遍历oldValObj
        for (var key in oldValObj) {
            if (object[key] !== undefined) {
                oldValObj[key] = object[key];
            }
        }



        // 对于 默认值 最终数据的验证

        // repeat 必须是 布尔类型
        if (typeof (oldValObj.repeat) !== 'boolean') return 'repeat参数必须是布尔类型';

        // length 必须可以转化为数值类型
        oldValObj.length = Number(oldValObj.length);
        if (isNaN(oldValObj.length)) return 'length参数必须可以转化为数值类型';


        // str 必须是 字符串类型
        if (typeof (oldValObj.str) !== 'string') return 'str参数必须是字符串类型';
    }

    // 定义变量储存验证码
    var vc = '';

    // 定义死循环 
    while (true) {
        // 获取随机索引下标
        var index = parseInt(Math.random() * oldValObj.str.length);

        // 判断 oldValObj中repeat的属性值
        if (oldValObj.repeat) {
            // 内容可以重复 直接拼接
            vc += oldValObj.str[index];

        } else {
            // 内容不能重复 验证后拼接
            if (!vc.includes(oldValObj.str[index])) {
                // 随机字符 不在验证码字符串中 再执行拼接操作
                vc += oldValObj.str[index];
            }
        }


        // 验证码长度 为 oldValObj.length 终止 死循环
        if (vc.length === oldValObj.length) break;
    }

    // 返回值是生成的验证码字符串
    return vc;

}


/*
    myGetUrlValObj 获取地址栏数据参数 转化为对象
        @return object  获取浏览器地址栏数据 转化的对象
*/ 

function myGetUrlValObj(){
    // 定义一个空对象 存储 结果
    var obj = {} ;

    // 获取浏览器地址栏数据字符串 不要一个字符?问号
    var str = window.location.search.substr( 1 );

    // 将字符串 按照 & 符号 分割为数组
    var arr1 = str.split('&');

    // 循环遍历数组 
    arr1.forEach( function(item){
        // item中存储的是 键值对字符串 
        // 以 = 等号 为间隔 分割为数组
        var arr2 = item.split('=') ;

        // arr2[0] 存储的是 键名 
        // arr2[1] 存储的是 键值 

        // 以 arr2[0] 键名 从 对象中 调用数据
        if( obj[ arr2[0] ] === undefined ){
            // 如果 调用结果 是 undefined 
            obj[ arr2[0] ] = window.decodeURIComponent( arr2[1] );

        }else{
            // 如果调用结果 不是 undefined

            // 判断 obj[ arr2[0] ] 存储数据的数据类型
            if( typeof( obj[ arr2[0] ] ) === 'string' ){
                // 如果 是 字符串类型 
                // 存储数据 赋值为 数组 
                // 数组的第一个单元 是 obj[ arr2[0] ] 存储的原始数据
                // 数组的第二个单元 是 obj[ arr2[1] ] 对应的键值
                obj[ arr2[0] ] = [ obj[ arr2[0] ] , window.decodeURIComponent( arr2[1] )  ];

            }else{
                // 如果 不是 字符串类型 一定是 数组类型
                // 直接在末位新增 键值arr2[1]
                obj[ arr2[0] ].push( window.decodeURIComponent( arr2[1] ) );
            }
        }
    })

    // return 返回 对象
    return obj ;

}
